#ifndef DATE_TIME_H
#define DATE_TIME_H

#include <ctime>
#include <string>
#include <memory>

namespace base
{
namespace utils
{
/**
 * @brief:  时间处理工具库，精确到毫秒
 * @author: sherlock_lht
 */
class DateTime
{
public:
    /**
     * 返回当前的时间戳转换的秒数(从1970-01-01T00:00:00开始计算)
     */
    static long long currentSecond();

    /**
     * 返回当前时间戳
     */
    static DateTime currentDateTime();

    /**
     * tm转换成秒数(从1970-01-01T00:00:00开始计算)
     */
    static long long tm2Second(tm *tm);

    /**
     * 秒数(从1970-01-01T00:00:00开始计算)转换成tm
     */
    static std::tm second2Tm(long long second, bool *isOk = nullptr);

public:
    DateTime();
    DateTime(const DateTime &dateTime);
    explicit DateTime(std::tm *tm);
    explicit DateTime(long long second, long long msecond);
    virtual ~DateTime();

    DateTime addDays(int days) const;

    DateTime addSecond(long long seconds) const;

    DateTime addMillSecond(long long msecond) const;

    /**
     * 格式化时间
     * These expressions may be used for the date:
     * d    :   the day as number without a leading zero (1 to 31)
     * dd   :   the day as number with a leading zero (01 to 31)
     * ddd  :   the abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses the system locale to localize the name, i.e. QLocale::system().
     * dddd :   the long localized day name (e.g. 'Monday' to 'Sunday'). Uses the system locale to localize the name, i.e. QLocale::system().
     * M    :   the month as number without a leading zero (1-12)
     * MM   :   the month as number with a leading zero (01-12)
     * MMM  :   the abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses the system locale to localize the name, i.e. QLocale::system().
     * MMMM :   the long localized month name (e.g. 'January' to 'December'). Uses the system locale to localize the name, i.e. QLocale::system().
     * yy   :   the year as two digit number (00-99)
     * yyyy :   the year as four digit number
     * h    :   the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
     * hh   :   the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
     * H    :   the hour without a leading zero (0 to 23, even with AM/PM display)
     * HH   :   the hour with a leading zero (00 to 23, even with AM/PM display)
     * m    :   the minute without a leading zero (0 to 59)
     * mm   :   the minute with a leading zero (00 to 59)
     * s    :   the second without a leading zero (0 to 59)
     * ss   :   the second with a leading zero (00 to 59)
     * z    :   the milliseconds without leading zeroes (0 to 999)
     * zzz  :   the milliseconds with leading zeroes (000 to 999)
     * AP/A :   use AM/PM display. A/AP will be replaced by either "AM" or "PM".
     * ap/a :   use am/pm display. a/ap will be replaced by either "am" or "pm".
     */
    std::string toString(const std::string &format) const;

    long long toSecond() const;

    long long toMilliSecond() const;

private:
    time_t sec_;
    long long int msec_;
};
}
}

#endif //DATE_TIME_H
